home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / smaltalk / manchest.lha / MANCHESTER / usenet / st80_pre4 / newbrowser.st < prev    next >
Text File  |  1993-07-24  |  17KB  |  735 lines

  1. "    NAME        newbrowser
  2.     AUTHOR        huba@unidoi5 (Hubert Baumeister)
  3.     FUNCTION    improved system browser
  4.     ST80-VERSIONS    2.3, 2.5
  5.     PREREQUISITES    
  6.     THEN FILE IN    
  7.     CONFLICTS WITH    
  8.     DISTRIBUTION      world
  9.     VERSION    ID    1.1
  10.     VERSION DATE    18 Jan 90
  11. SUMMARY A browser that indents categories
  12. "
  13. '
  14. From: baumeist@exunido.uucp (Hubert Baumeister)
  15. Newsgroups: comp.lang.smalltalk
  16. Subject: Code for a new SystemBrowser
  17. Summary: New SystemBrowser shows categories as hierarchies
  18. Message-ID: <1907@laura.UUCP>
  19. References: <4811d5e9.20b6d@apollo.HP.COM>
  20.  
  21. In ParcPlace Smalltalk categories are a useful tool to group classes 
  22. together that have the same function or belong to the same program. 
  23. As the number of classes and categories increase a simple grouping 
  24. scheme for classes is not enough; hierarchies are needed. This is 
  25. done in Smalltalk by prefixing categories like:
  26.  
  27. Magnitude-General
  28. Magnitude-Numbers
  29. ...
  30. Tools-Programming
  31. Tools-Programming-New
  32. Tools-Inspector
  33. Tools-File Model
  34. Tools-Form editing
  35. Tools-Terminal
  36. Tools-Transcript
  37. Tools-Projects
  38. Tools-Changes
  39. ...
  40.  
  41. I have written a new SystemBrowser that shows the categories 
  42. as an indented list like:
  43. Magnitude
  44.     General
  45.     Numbers
  46. ...
  47. Tools
  48.     Programming
  49.         New
  50.     Inspector
  51.     File Model
  52.     ...
  53. ...
  54. It is possible to hide parts of the hierarchy like:
  55. -Magnitude
  56. ...
  57. Tools
  58.     -Programming
  59.     Inspector
  60.     File Model
  61.     ...
  62. ...
  63. Hidden sublists are indicated by a dash in the first position.
  64.  
  65. It is now possible to file out all categories that have a 
  66. common prefix to one file.
  67.  
  68. e.g: filing out Tools yields a fileOut of 
  69. Tools-Programming-New
  70. Tools-Inspector
  71. Tools-File Model
  72. ...
  73. into one file.
  74.  
  75. The same works for removing categories.
  76.  
  77. The NewBrowser can be filed in in ParcPlace Smalltalk 2.3 
  78. and 2.5. Only one method changes for the different versions. 
  79. That is NewBrowser>catgory functions>fileOutCategories. 
  80. This method uses file handling and has to be adapted. This 
  81. can be done by installing 
  82. NewBrowser>category functions>fileOutCategories23 
  83. (for 2.3) or NewBrowser>category functions>fileOutCategories25 
  84. (for 2.5) as NewBrowser>category functions>fileOutCategories. 
  85. Default is the installation for 2.5.
  86.  
  87. To open the new browser evaluate:
  88.     NewBrowserView openOn: SystemOrganization
  89.  
  90. I hope you find this tool as useful as I do.
  91.  
  92. Hubert
  93. (Hubert Baumeister
  94.     baumeist@exunido
  95.     or
  96.     huba@unidoi5)
  97. '
  98.  
  99. Object variableSubclass: #CategoryTree
  100.     instanceVariableNames: 'sons parent contents hidden isCategory '
  101.     classVariableNames: ''
  102.     poolDictionaries: ''
  103.     category: 'Tools-Programming-New'!
  104. CategoryTree comment:
  105. 'Instances of me represent a Tree.
  106.  
  107. Instance variables:
  108.     sons        <OrderedCollection>     the subtrees.
  109.     parent        <CatgoryTree>            the tree my instance is subtree of.
  110.     contents    <String>                a part of a categorie name e.g: ''Programming''
  111.     hidden        <Boolean>                if hidden is true the subtrees are invisible.
  112.     isCategory <Boolean>                if the concatenated contents from root downto self is the name of a category.'!
  113.  
  114.  
  115. !CategoryTree methodsFor: 'accessing'!
  116.  
  117. contents
  118.     contents isNil ifTrue: [contents _ ' '].
  119.     ^contents!
  120.  
  121. contents: obj
  122.     contents _ obj!
  123.  
  124. hiddenSubtrees: bool 
  125.     hidden _ bool!
  126.  
  127. isCategory
  128.     isCategory isNil ifTrue: [isCategory _ false].
  129.     ^isCategory!
  130.  
  131. isCategory: bool
  132.     isCategory _ bool!
  133.  
  134. parent
  135.     ^parent!
  136.  
  137. parent: aTree
  138.     parent_aTree!
  139.  
  140. parentsDo: aBlock 
  141.     self isRoot not
  142.         ifTrue: 
  143.             [aBlock value: self parent.
  144.             self parent parentsDo: aBlock]!
  145.  
  146. path
  147.     "Returns the concatenated contents from root to self without the 
  148.     contents of root."
  149.  
  150.     | path |
  151.     path _ self contents.
  152.     self isRoot ifFalse: [self parent isRoot ifFalse: [path _ self parent path , '-' , path]].
  153.     ^path!
  154.  
  155. size
  156.     ^self sons size!
  157.  
  158. toggleHidden
  159.     hidden _ self hiddenSubtrees not.! !
  160.  
  161. !CategoryTree methodsFor: 'adding'!
  162.  
  163. add: aSubtree 
  164.     aSubtree parent: self.
  165.     ^self sons addLast: aSubtree! !
  166.  
  167. !CategoryTree methodsFor: 'testing'!
  168.  
  169. hiddenSubtrees
  170.     hidden isNil ifTrue: [hidden _ true].
  171.     ^hidden!
  172.  
  173. isLeaf
  174.     ^self size = 0!
  175.  
  176. isRoot
  177.     ^self parent isNil! !
  178.  
  179. !CategoryTree methodsFor: 'removing'!
  180.  
  181. remove: tree
  182.     ^self sons remove: tree!
  183.  
  184. removeIfTrue: aBlock 
  185.     "Remove all the subtrees from self for which aBlock value: subtree is 
  186.     true"
  187.  
  188.     self sons copy do: [:subtree | (aBlock value: subtree)
  189.             ifTrue: [self remove: subtree]
  190.             ifFalse: [subtree removeIfTrue: aBlock]]! !
  191.  
  192. !CategoryTree methodsFor: 'enumerating'!
  193.  
  194. allSubtreesDo: aBlock 
  195.     "Enumerate all subtrees of self regardless of the hidden flag and aplly 
  196.     aBlock to them"
  197.  
  198.     aBlock value: self.
  199.     self do: [:st | st allSubtreesDo: aBlock]!
  200.  
  201. detect: aBlock 
  202.     ^self detect: aBlock ifNone: [self error: 'Element not found']!
  203.  
  204. detect: aBlock ifNone: exceptionBlock 
  205.     "Find one subtree for which aBlock value: subtree is true. If there is 
  206.     none execute exceptionBlock"
  207.  
  208.     (aBlock value: self)
  209.         ifTrue: [^self].
  210.     self allSubtreesDo: [:tree | (aBlock value: tree)
  211.             ifTrue: [^tree]].
  212.     ^exceptionBlock value!
  213.  
  214. detectSubtree: aBlock 
  215.     ^self detectSubtree: aBlock ifNone: [self error: 'Element not found']!
  216.  
  217. detectSubtree: aBlock ifNone: exceptionBlock 
  218.     "Find one of my sons for which aBlock value: subtree is true. If there 
  219.     is none execute exceptionBlock"
  220.  
  221.     self do: [:tree | (aBlock value: tree)
  222.             ifTrue: [^tree]].
  223.     ^exceptionBlock value!
  224.  
  225. do: aBlock 
  226.     "Enumerate all my sons and apply aBlock to them."
  227.  
  228.     ^self sons do: aBlock!
  229.  
  230. preorder
  231.     "This yields a collection of all subtrees of me in preorder without the 
  232.     sons of hidden subtrees"
  233.  
  234.     | coll |
  235.     coll _ OrderedCollection new.
  236.     self preorderDo: [:t | coll add: t].
  237.     ^coll!
  238.  
  239. preorderDo: aBlock 
  240.     "Enumerate all subtrees without the sons of the subtrees with hidden 
  241.     = true and apply aBlock to them."
  242.  
  243.     aBlock value: self.
  244.     self hiddenSubtrees ifFalse: [self do: [:c | c preorderDo: aBlock]]! !
  245.  
  246. !CategoryTree methodsFor: 'printing'!
  247.  
  248. printOn: aStream 
  249.     "Print contents on a stream indented by the height of self minus 1. If 
  250.     I have hidden sons append a dash before the contents"
  251.  
  252.     | count |
  253.     count _ 0.
  254.     self parentsDo: [:p | count _ count + 1].
  255.     count _ count - 1.
  256.     count timesRepeat: [aStream nextPutAll: '   '].
  257.     self isLeaf not & self hiddenSubtrees ifTrue: [aStream nextPut: $-].
  258.     aStream nextPutAll: self contents! !
  259.  
  260. !CategoryTree methodsFor: 'private'!
  261.  
  262. size: number 
  263.     sons _ OrderedCollection new: number.
  264.     number timesRepeat: [sons add: nil]!
  265.  
  266. sons
  267.     sons isNil ifTrue: [sons _ OrderedCollection new].
  268.     ^sons! !
  269. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  270.  
  271. CategoryTree class
  272.     instanceVariableNames: ''!
  273.  
  274.  
  275. !CategoryTree class methodsFor: 'instance creation'!
  276.  
  277. new: number
  278.     ^self basicNew size: number! !
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339. Browser subclass: #NewBrowser
  340.     instanceVariableNames: 'categoryTree categorySelection '
  341.     classVariableNames: 'NewCategoryMenu '
  342.     poolDictionaries: ''
  343.     category: 'Tools-Programming-New'!
  344. NewBrowser comment:
  345. 'Instances of me are Browsers that show the categories as indented list.
  346.  
  347. e.g:
  348. ...
  349. -Interface
  350. Tools
  351.     Programming
  352.         New
  353.     Inspector
  354.     File Model
  355.     ...
  356. -System
  357. ...
  358.  
  359. instead of:
  360.  
  361. Interface-...
  362. Tools-Programming-New
  363. Tools-Inspector
  364. Tools-File Model
  365. ...
  366. System-...
  367.  
  368. Sublists can be hidden:
  369.  
  370. e,g:
  371. ...
  372. -Interface
  373. -Tools
  374. -System
  375. ...
  376.  
  377. Hidden sublists are indicated by a dash in the first position.
  378.  
  379. It is now possible to file out all categories that have a common prefix to one file.
  380.  
  381. e.g: filing out Tools yields a fileOut of 
  382. Tools-Programming-New
  383. Tools-Inspector
  384. Tools-File Model
  385. ...
  386. into one file.
  387.  
  388. The same works for removing categories.
  389.  
  390. Instance variables:
  391.     categoryTree        <CategoryTree>  Holds organization categories as a tree.
  392.     categorySelection  <CategoryTree>  Holds the selected subtree of categoryTree.
  393.  
  394. To open a view on an instance of me evaluate:
  395.     NewBrowserView openOn: SystemOrganization
  396.  
  397. (c) Jan 1990 by Hubert Baumeister
  398. (huba@unidoi5)'!
  399.  
  400.  
  401. !NewBrowser methodsFor: 'category list'!
  402.  
  403. category: aSymbol
  404.     aSymbol = '**Hierarchy**' ifTrue: [^super category: aSymbol].
  405.     self setCategorySelectionFor: aSymbol.
  406.     super category: aSymbol!
  407.  
  408. categoryList
  409.     | l |
  410.     categoryTree isNil
  411.         ifTrue: 
  412.             [categoryTree _ CategoryTree new.
  413.             organization categories do: [:cat | self treeAddCategory: cat]].
  414.     categoryTree hiddenSubtrees: false.
  415.     l _ categoryTree preorder.
  416.     l removeFirst.
  417.     ^l!
  418.  
  419. categoryMenu
  420.     "self flushMenus"
  421.  
  422.     categorySelection == nil
  423.         ifTrue: [^ActionMenu
  424.                 labels: 'add category\update\edit all\find class' withCRs
  425.                 lines: #(1 3 )
  426.                 selectors: #(addCategory updateCategories editCategories findClass )]
  427.         ifFalse: [NewCategoryMenu isNil ifTrue: [NewCategoryMenu _ ActionMenu
  428.                             labels: 'file out\print out\spawn\add category\rename\remove\update\edit all\find class\hide/show' withCRs
  429.                             lines: #(3 6 8 )
  430.                             selectors: #(fileOutCategory printOutCategory spawnCategory addCategory renameCategory removeCategory updateCategories editCategories findClass categoryToggleHidden )]].
  431.     ^NewCategoryMenu!
  432.  
  433. categorySelection
  434.     ^categorySelection!
  435.  
  436. categorySelection: aTree 
  437.     | cat |
  438.     categorySelection _ aTree.
  439.     aTree isNil ifTrue: [^super category: nil].
  440.     (organization categories includes: (cat _ aTree path asSymbol))
  441.         ifFalse: [cat _ nil].
  442.     super category: cat!
  443.  
  444. newCategoryList: aSymbol 
  445.     "Set the currently selected category to be aSymbol."
  446.  
  447.     self updateCategoryTree.
  448.     self setCategorySelectionFor: aSymbol.
  449.     super newCategoryList: aSymbol! !
  450.  
  451. !NewBrowser methodsFor: 'category functions'!
  452.  
  453. categoryToggleHidden
  454.     categorySelection toggleHidden.
  455.     self changed: #category!
  456.  
  457. fileOutCategory
  458.     "This is the fileOutCategory method for ParcPlace Smalltalk >= 2.4. 
  459.     Remove 25 in the selector of the method and accept it when you 
  460.     are using 2.5"
  461.  
  462.     | fileName aFileStream |
  463.     categorySelection path , '*'.
  464.     fileName _ Filename
  465.                 request: 'File out on'
  466.                 initially: (self contractString: categorySelection path to: 8)
  467.                         , '.st'
  468.                 shouldExist: false.
  469.     fileName = '' ifTrue: [^nil].
  470.     aFileStream _ (Filename named: fileName) writeStream.
  471.     categorySelection allSubtreesDo: [:tree | tree isCategory
  472.             ifTrue: 
  473.                 [organization fileOutCategory: tree path asSymbol on: aFileStream.
  474.                 aFileStream cr; cr]].
  475.     aFileStream close!
  476.  
  477. fileOutCategory23
  478.     "This is the fileOutCategory method for ParcPlace Smalltalk =< 2.3. 
  479.     Remove 23 in the selector of the method and accept it when you 
  480.     are using 2.3"
  481.  
  482.     | fileName aFileStream |
  483.     categorySelection path , '*'.
  484.     fileName _ FillInTheBlank request: 'File out on' initialAnswer: (self contractString: categorySelection path to: 8)
  485.                     , '.st'.
  486.     fileName = '' ifTrue: [^nil].
  487.     aFileStream _ FileStream newFileNamed: fileName.
  488.     categorySelection allSubtreesDo: [:tree | tree isCategory
  489.             ifTrue: 
  490.                 [organization fileOutCategory: tree path asSymbol on: aFileStream.
  491.                 aFileStream cr; cr]].
  492.     aFileStream close!
  493.  
  494. fileOutCategory25
  495.     "This is the fileOutCategory method for ParcPlace Smalltalk >= 2.4. 
  496.     Remove 25 in the selector of the method and accept it when you 
  497.     are using 2.5"
  498.  
  499.     | fileName aFileStream |
  500.     categorySelection path , '*'.
  501.     fileName _ Filename
  502.                 request: 'File out on'
  503.                 initially: (self contractString: categorySelection path to: 8)
  504.                         , '.st'
  505.                 shouldExist: false.
  506.     fileName = '' ifTrue: [^nil].
  507.     aFileStream _ (Filename named: fileName) writeStream.
  508.     categorySelection allSubtreesDo: [:tree | tree isCategory
  509.             ifTrue: 
  510.                 [organization fileOutCategory: tree path asSymbol on: aFileStream.
  511.                 aFileStream cr; cr]].
  512.     aFileStream close!
  513.  
  514. removeCategory
  515.     | classes pattern changed |
  516.     categorySelection isCategory & categorySelection isLeaf ifTrue: [^super removeCategory].
  517.     self changeRequest ifFalse: [^self].
  518.     changed _ false.
  519.     pattern _ categorySelection path , '*'.
  520.     (organization categories select: [:cat | pattern match: cat])
  521.         do: 
  522.             [:cat | 
  523.             classes _ organization superclassOrder: cat.
  524.             classes isEmpty
  525.                 ifTrue: 
  526.                     [organization removeCategory: cat.
  527.                     changed _ true]
  528.                 ifFalse: [(self confirm: 'Are you certain that you want to
  529. remove all classes in ' , cat , '?')
  530.                         ifTrue: 
  531.                             [classes reverseDo: [:cls | cls removeFromSystem].
  532.                             organization removeCategory: cat.
  533.                             changed _ true]]].
  534.     changed
  535.         ifTrue: 
  536.             [Smalltalk changes reorganizeSystem.
  537.             self newCategoryList: nil]!
  538.  
  539. renameCategory
  540.     categorySelection isCategory ifTrue: [super renameCategory]!
  541.  
  542. spawnCategory
  543.     categorySelection isCategory ifTrue: [super spawnCategory]! !
  544.  
  545. !NewBrowser methodsFor: 'private'!
  546.  
  547. contractString: aString to: charcount 
  548.     "This shortens aString with parts seperated by dashes to a String of 
  549.     size charcount. This is useful for systems with short filenames, like 
  550.     MS-Dos or Atari TOS."
  551.  
  552.     | rs strings newName nchar rest last |
  553.     strings _ OrderedCollection new.
  554.     rs _ ReadStream on: aString.
  555.     [rs atEnd]
  556.         whileFalse: [strings add: (rs upTo: $-)].
  557.     nchar _ charcount // strings size max: 1.
  558.     rest _ charcount \\ strings size.
  559.     newName _ String new.
  560.     strings do: [:str | newName _ newName , (str copyFrom: 1 to: (nchar min: str size))].
  561.     rest ~= 0
  562.         ifTrue: 
  563.             [last _ strings last.
  564.             newName _ newName , (strings last copyFrom: nchar + 1 to: (nchar + rest min: last size))].
  565.     ^newName!
  566.  
  567. setCategorySelectionFor: aSymbol 
  568.     "A new categorie should be selected. This methods find the subtree 
  569.     of categoryTree that has aSymbol as path"
  570.  
  571.     aSymbol isNil ifTrue: [^self].
  572.     categoryTree isNil ifTrue: [self categoryList].
  573.     categorySelection _ categoryTree detect: [:tree | tree path = aSymbol].
  574.     categorySelection parentsDo: [:tree | tree hiddenSubtrees: false]!
  575.  
  576. treeAddCategory: symbol 
  577.     "Decompose a symbol in parts seperated by dashes and insert the 
  578.     parts into categoryTree."
  579.  
  580.     | rs tree newTree contents st  |
  581.     rs _ ReadStream on: symbol.
  582.     tree _ categoryTree.
  583.     [rs atEnd]
  584.         whileFalse: 
  585.             [contents _ rs upTo: $-.
  586.             st _ tree detectSubtree: [:subtree | subtree contents = contents]
  587.                         ifNone: 
  588.                             [newTree _ CategoryTree new contents: contents.
  589.                             tree add: newTree.
  590.                             newTree].
  591.             tree _ st].
  592.     tree isCategory: true!
  593.  
  594. updateCategoryTree
  595.     "ogranization categories may have changed. Update the 
  596.     categoryTree."
  597.  
  598.     | categories categoriesToRemove path |
  599.     categoryTree isNil ifTrue: [^self].
  600.     categoriesToRemove _ OrderedCollection new.
  601.     categories _ organization categories asOrderedCollection.
  602.     categoryTree
  603.         allSubtreesDo: 
  604.             [:tree | 
  605.             path _ tree path asSymbol.
  606.             categories remove: path ifAbsent: [tree isCategory ifTrue: [categoriesToRemove add: tree]]].
  607.     categoriesToRemove isEmpty not
  608.         ifTrue: 
  609.             [categoryTree removeIfTrue: [:tree | categoriesToRemove includes: tree].
  610.             categoryTree removeIfTrue: [:tree | tree isLeaf & tree isCategory not]].
  611.     categories do: [:cat | self treeAddCategory: cat]! !
  612. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  613.  
  614. NewBrowser class
  615.     instanceVariableNames: ''!
  616.  
  617.  
  618. !NewBrowser class methodsFor: 'class initialization'!
  619.  
  620. flushMenus
  621.     "self flushMenus."
  622.     "Causes all menus to be newly created (so changes appear)"
  623.  
  624.     super flushMenus.
  625.     NewCategoryMenu _ nil! !
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683.  
  684.  
  685.  
  686. BrowserView subclass: #NewBrowserView
  687.     instanceVariableNames: ''
  688.     classVariableNames: ''
  689.     poolDictionaries: ''
  690.     category: 'Tools-Programming-New'!
  691. NewBrowserView comment:
  692. 'My instances are BrowserViews. I only change the creation message for a new SystemBrowser.'!
  693.  
  694.  
  695. !NewBrowserView methodsFor: 'subview creation'!
  696.  
  697. addCategoryView: area on: aBrowser readOnly: RO
  698.     self addSubView:
  699.         (SelectionInListView on: aBrowser printItems: true oneItem: RO
  700.             aspect: #category change: #categorySelection: list: #categoryList
  701.             menu: #categoryMenu initialSelection: #categorySelection)
  702.         in: area borderWidth: 1! !
  703. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  704.  
  705. NewBrowserView class
  706.     instanceVariableNames: ''!
  707.  
  708.  
  709. !NewBrowserView class methodsFor: 'instance creation'!
  710.  
  711. openOn: anOrganizer 
  712.     "Create and schedule a browser on an entire collection of organized 
  713.     classes. 
  714.     For example, evaluate 
  715.         BrowserView openOn: SystemOrganization."
  716.  
  717.     | topView aBrowser topY bottomY metaY |
  718.     aBrowser _ NewBrowser new on: anOrganizer.
  719.     topY _ 0.35.
  720.     "change this to re-proportion system browser"
  721.     bottomY _ 1 - topY.
  722.     metaY _ 0.05.
  723.     "change this to re-proportion system browser"
  724.     (topView _ self model: aBrowser label: 'System Browser' minimumSize: 400 @ 250)
  725.         addCategoryView: (0 @ 0 extent: 0.25 @ topY) on: aBrowser readOnly: false;
  726.         addClassView: (0.25 @ 0 extent: 0.25 @ (topY - metaY)) on: aBrowser readOnly: false;
  727.         addMetaView: (0.25 @ (topY - metaY) extent: 0.25 @ metaY) on: aBrowser readOnly: false;
  728.         addProtocolView: (0.5 @ 0 extent: 0.25 @ topY) on: aBrowser readOnly: false;
  729.         addSelectorView: (0.75 @ 0 extent: 0.25 @ topY) on: aBrowser readOnly: false;
  730.         addTextView: (0 @ topY extent: 1.0 @ bottomY) on: aBrowser initialSelection: nil.
  731.     topView icon: (Icon constantNamed: #default).
  732.     topView controller open! !
  733.  
  734.  
  735.